package com.codefactory.geneticalgorithm;

import java.util.Vector;
import org.jgap.FitnessFunction;
import org.jgap.Gene;
import org.jgap.IChromosome;

/**
 * Целевая функция
 * @author random
 */
public class MachineFitnessFunction extends FitnessFunction{

    /**
     * Значение критерия эффективности
     * @param ic
     * @return 
     */
    @Override
    protected double evaluate(IChromosome ic) {
        MachineInfo summ = sumRepairCosts(ic);
        double result = 0.5 * dificulty(summ) - 0.5 * usage(summ);
        return result;
    }
    
    /**
     * Суммирует количественные характеристики запланированных к ремонту машин.
     * @param ic
     * @return 
     */
    private static MachineInfo sumRepairCosts(IChromosome ic){
        MachineInfo result = new MachineInfo();
        Gene[] genes = ic.getGenes();
        for (int i = 0; i < genes.length; i++) {
            Vector<Vector<Boolean>> schedule = (Vector<Vector<Boolean>>)genes[i].getAllele();
            Vector<Boolean> repairsSchedule = schedule.firstElement();
            Vector<Boolean> maintenanceSchedule = schedule.lastElement();
            MachineInfo mi = (MachineInfo) genes[i].getApplicationData();
            for(int j = 0; j < repairsSchedule.size(); j++){
                if (repairsSchedule.get(j)) {
                    result.setRepairCosts(result.getRepairCosts() + mi.getRepairCosts());
                    result.setRepairTime(result.getRepairTime() + mi.getRepairTime());
                    result.setWorkerCount(result.getWorkerCount() + mi.getWorkerCount());
                }
                if (maintenanceSchedule.get(j)){
                    result.setRepairCosts(result.getRepairCosts() + mi.getMaintenanceCosts());
                    result.setRepairTime(result.getRepairTime() + mi.getMaintenanceTime());
                    result.setWorkerCount(result.getWorkerCount() + mi.getMaintenanceWorkerCount());
                }
            }
        }
        return result;
    }
    
    /**
     * Суммарная сложность ремонта машин.
     * @param summInfo
     * @return 
     */
    private static double dificulty(MachineInfo summInfo){
        double result = 
            0.3*summInfo.getRepairCosts()+0.4*summInfo.getRepairTime()+0.3*summInfo.getWorkerCount();
        return result;
    }
    
    /**
     * Суммарное использование ремонтируемых машин.
     * @param summInfo
     * @return 
     */
    private static double usage(MachineInfo summInfo){
        return 0D;
    }
    
}
